Skip to content

livereload.js が使うポートを http serve が使う TCP ポートを併用するように修正#6

Open
tamx wants to merge 5 commits into
mattn:masterfrom
tamx:master
Open

livereload.js が使うポートを http serve が使う TCP ポートを併用するように修正#6
tamx wants to merge 5 commits into
mattn:masterfrom
tamx:master

Conversation

@tamx

@tamx tamx commented Dec 17, 2025

Copy link
Copy Markdown

変な動きしていたところは直りました。
これで、 livereload.js が使うポートを http serve が使う TCP ポートを併用するように修正できたと思います。
よろしくお願いします。

@mattn

mattn commented Dec 17, 2025

Copy link
Copy Markdown
Owner

ありがとうございます。
1点、申し訳ないですがオプション化して頂けないでしょうか。

実はこの 35729 というポート番号は、LiveReload という機能が作られた際から使われている番号でして、多くの LiveReload ツールでデフォルトポートとして使われております。例: Grunt, Gulp, Webpack Dev Server, Spring boot DevTools, Python livereload など

そして、それとは別に livereload 用のブラウザ拡張がありまして、そのブラウザ拡張が 35729 をめがけてページにリロードを送ってくる様になっています。
僕のツールは単体で動作するため、このブラウザ拡張は不要なのですが、できれば LiveReload 系ツールの流儀として合わせておきたいと思っています。
ただせっかく対応頂き、余計なポートをあけずに動作する様にしていただいているので、オプションの形を取らせて頂きたいです。

方法は以下のどちらでも構いません。

  1. -usehttpport の bool 型フラグが on の時は goroutine の生成をスキップする (関数化しておくと良さそうです)
  2. 環境変数 MKUP_USEHTTPPORT が空でない場合は 1 の内容と同じ動作をする

@tamx

tamx commented Dec 17, 2025

Copy link
Copy Markdown
Author

了解です。オプションで設定できるように修正します!

@tamx

tamx commented Dec 20, 2025

Copy link
Copy Markdown
Author

1 のオプションで指定できるようにしてみました。これでどうでしょうか?

Comment thread main.go Outdated
+ (location.host || 'localhost').split(':')[0]
+ ':35729/livereload.js?snipver=1"></'
+ (location.host || 'localhost')
+ '/_assets/livereload.js?snipver=1"></'

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここに指定したポートが入るのではないでしょうか。

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

location.host はポート番号を含んでいて、このスクリプトが動いているということは、この HTML が正しく読み込めていて、参照する location.host がポート番号付きで見えていると思います。

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この修正によりポート番号 35729 が消えてしまっているようです。

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http ポートで同じように返すようにしているので、問題ないかと思ったんですが、どうでしょうか?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#6 (comment)

ここに書いた様に、ポート 35729 からサーブする実装を残して頂きたいです。

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-usehttpport が指定されていないときには 35729 ポートを使ったほうがいい感じですね?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

はい。livereload の本来のポート番号は 35729 ですので、それをデフォルトとして残したいです。

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

了解です。修正します!

@tamx

tamx commented Jan 22, 2026

Copy link
Copy Markdown
Author

たいへん遅くなりましたが、修正しました。よろしくお願いします!

@tamx

tamx commented Apr 26, 2026

Copy link
Copy Markdown
Author

お忙しい所すみません。こちらの修正、どうでしょうか?

@mattn

mattn commented Apr 26, 2026

Copy link
Copy Markdown
Owner

修正ありがとうございます。-usehttpport 指定時は意図通りに動くのですが、指定しないデフォルト動作(35729 を別ポートで使う側)で、2つの理由から LiveReload が動かない状態になっています。順に説明します。

① HTML テンプレートの URL が二重ポートになる

main.go のテンプレートをこう変更されています:

<script>document.write('<script src="'
    + location.protocol + '//'
    + (location.host || 'localhost')
    + '%s/_assets/livereload.js?snipver=1"></'
    + 'script>')</script>

ここで %s には livereloadPortAddr が入りますが、デフォルトでは ":35729" です。
一方 JavaScript の location.hostすでにポート番号を含む 値(例: localhost:8000)を返します。
そのため最終的に生成される URL は

http://localhost:8000:35729/_assets/livereload.js?snipver=1

となり、host が二重ポートを持った不正 URL になってしまいます。ブラウザはこれを解決できないので livereload.js が読み込めません。

元コードでは (location.host || 'localhost').split(':')[0] として ホスト名だけ を取り出してから :35729/livereload.js を結合していたため、この問題は起きませんでした。

-usehttpport 指定時は livereloadPortAddr = "" になって URL が http://localhost:8000/_assets/livereload.js と健全な形になるので、こちら側だけ動いて見える、という状況です。

② LiveReload の「お作法」パスが 35729 側から消えている

僕が前回コメントでお願いしたのは、デフォルトでは従来通り 35729 を維持して LiveReload ブラウザ拡張に合わせる、という意図でした。LiveReload ブラウザ拡張は 35729 ポートに対して

  • GET /livereload.js(埋め込みスクリプト)
  • /livereload(WebSocket)

を期待します。元コードは goroutine の中で 専用の http.NewServeMux() を立て、

mux.HandleFunc("/livereload.js", ...)  // 埋め込み JS を返す
mux.Handle("/", lrs)                   // WebSocket
http.ListenAndServe(":35729", mux)

として上記 2 つを 35729 で提供していました。

新しいコードでは 35729 用の goroutine が http.DefaultServeMux をそのまま使う実装になっています:

Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    log.Printf(...)
    http.DefaultServeMux.ServeHTTP(w, r)
}),

http.DefaultServeMux 側にはメインアプリの //_assets//livereload(WebSocket) は登録されていますが、/livereload.js というパスは登録されていません/_assets/livereload.js に変わっているため)。
結果、ブラウザ拡張が http://localhost:35729/livereload.js を取りに来ても 404 が返り、拡張からの LiveReload が機能しません。これだと「LiveReload 系ツールの流儀に合わせる」目的のデフォルト動作が壊れた形になってしまいます。

修正方針の提案

デフォルト挙動と -usehttpport 指定時で「テンプレート」と「ハンドラの貼り方」を セットで 切り替える形が綺麗だと思います:

  • デフォルト時:
    • テンプレートは元の split(':')[0] + ':35729/livereload.js' 形式に戻す
    • 35729 goroutine は元のように専用 mux を立てて /livereload.js/(=lrs) を提供
  • -usehttpport 指定時:
    • テンプレートは現在の「同一ホスト・同一ポート+/_assets/livereload.js」を使う
    • HTTP サーバ側に /_assets/livereload.js(埋め込み JS)と /livereload(WebSocket=lrs)を貼る
    • goroutine は起動しない

前回コメントで触れた「関数化しておくと良さそう」というのは、まさにこの goroutine の中身 + テンプレート用パス文字列 を一つの関数にまとめておくと、フラグでまるっと切り替えられて読みやすいかな、という意図でした。

細かい点(任意)

  • if *usehttpport == true は Go の慣習だと if *usehttpport で十分です
  • フラグ説明文 "use livereload port with the same http port" は意図と少し読み違えそうなので、"serve LiveReload on the same port as HTTP" のような表現にすると分かりやすいかもしれません

@tamx

tamx commented Apr 26, 2026

Copy link
Copy Markdown
Author

了解です。修正します。お手数おかけします!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants